﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;

namespace CY_MVC.Core
{
    internal static class ResourceHelper
    {
        private static readonly Regex ResourceJsRegex = new Regex(@"<script\s*[""'/=\w]*\s*[""'/=\w]*\s*src=(""|')(?<path>[:\u002E\- /%&=\w]+\u002Ejs(|\?[\u002E\- /%&=\w]+))(""|')\s*[""'/=\w]*\s*[""'/=\w]*\s*((>\s*</script>)|(/>))", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        private static readonly Regex ResourceCssRegex = new Regex(@"<link\s*[""'/=\w]*\s*[""'/=\w]*\s*href=(""|')(?<path>[:\u002E\- /%&=\w]+\u002Ecss(|\?[\u002E\- /%&=\w]+))(""|')\s*[""'/=\w]*\s*[""'/=\w]*\s*((>\s*</link>)|(/>))", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        private static readonly Regex HeadRegex = new Regex("</head>", RegexOptions.Compiled | RegexOptions.IgnoreCase);

        private static readonly object Lockobject = new object();

        internal static readonly Dictionary<string, List<string>> Resources = new Dictionary<string, List<string>>();

        internal static string Generate(string p_ViewStr)
        {
            if (string.IsNullOrEmpty(p_ViewStr))
                return p_ViewStr;
            if (StaticConfig.JsMerge)
            {
                string Key;
                GetResourcePathsKey(p_ViewStr, ResourceJsRegex, out Key);
                if (!string.IsNullOrEmpty(Key))
                {
                    p_ViewStr = ResourceJsRegex.Replace(p_ViewStr, string.Empty);
                    p_ViewStr = HeadRegex.Replace(p_ViewStr, "<script src='" + StaticConfig.MVCHandler + "?jskey=" + Key + "' type='text/javascript' ></script>" + Environment.NewLine + "</head>");
                }
            }
            if (StaticConfig.CssMerge)
            {
                string Key;
                GetResourcePathsKey(p_ViewStr, ResourceCssRegex, out Key);
                if (!string.IsNullOrEmpty(Key))
                {
                    p_ViewStr = ResourceCssRegex.Replace(p_ViewStr, string.Empty);
                    p_ViewStr = HeadRegex.Replace(p_ViewStr, "<link href='" + StaticConfig.MVCHandler + "?csskey=" + Key + "' rel='stylesheet' type='text/css' />" + Environment.NewLine + "</head>");
                }
            }
            return p_ViewStr;
        }

        private static void GetResourcePathsKey(string p_ViewStr, Regex p_ResourceRegex, out string p_Key)
        {
            p_Key = string.Empty;
            var Mcs = p_ResourceRegex.Matches(p_ViewStr);
            if (Mcs.Count <= 0) return;

            var PathAll = string.Empty;
            var ResourcePaths = new List<string>();
            foreach (Match mc in Mcs)
            {
                ResourcePaths.Add(mc.Groups["path"].Value.Trim());
                PathAll += mc.Groups["path"].Value.Trim();
            }
            p_Key = PathAll.GetHashCode().ToString(CultureInfo.InvariantCulture).Replace("-", "0");
            if (!Resources.ContainsKey(p_Key))
            {
                lock (Lockobject)
                {
                    if (!Resources.ContainsKey(p_Key))
                    {
                        Resources.Add(p_Key, ResourcePaths);
                    }
                }
            }
        }
    }
}
